<?php

namespace api\mobile;

use app\common\model\Mobile;
use think\facade\Db;

/**
 * 乐充时代
 *
 * 接口文档：http://121.196.177.34/api/web/#/2
 * 登陆地址：http://121.196.177.34:1012/agent/login
 * 接口地址：http://121.196.177.34:1012/
 * 下单地址：http://121.196.177.34:1012/api/md5/submitorder
 * 余额查询地址：http://121.196.177.34:1012/api/md5/getbalance
 * 订单查询地址：http://121.196.177.34:1012/api/md5/queryorder
 * 注册地址：http://121.196.177.34:1012/agent/login
 */
class Lechong extends BaseModel
{
    private $header = [
        'Content-Type：application/x-www-form-urlencoded; charset=UTF-8',
    ];

    /**
     * 创建订单.
     *
     * @params
     * sub_order_id 系统订单号
     * amount 充值金额
     * mobile 充值号码
     *
     * $return  false/供应商订单号
     */
    public function create($order)
    {
        $params = [
            'agentcode' => $this->info['app_id'],
            'sellerid' => $order['sub_order_id'],
            'account' => base64_encode($order['mobile']),
            'code' => 'auto_rec',
            'num' => 1,
            'value' => fen2yuan($order['amount']), // 单位是元
            'notifyurl' => $this->notifyUrl,
            'remark' => '',
            'time' => date('YmdHis'),
        ];
        $params['sign'] = $this->getSign($params);
        $url = $this->info['url'] . '/api/md5/submitorder';
        $res = curlPost($url, http_build_query($params), $this->header, 40, true,false);
        $res = json_decode($res, true);

        $supplier_order_no = '';
        $returnCode = $res['recode'] ?? 's104';
        $remark = $res['msg'] ?? '下单失败';
        switch ($returnCode) {
            case 's100': // 请求成功
                $status = self::SUCCESS;
                break;
            case 's114': // 余额不足
                $status = self::LACK_OF_MONEY;
                $remark = '余额不足';
                break;
            case 's101': // 商户不存在
            case 's103': // 流水号为空
            case 's105': // IP不在白名单！
            case 's106': // 充值账号异常！
            case 's107': // 产品编码为空！
            case 's108': // 充值数量为空！
            case 's109': // 通知地址异常！
            case 's110': // 备注信息超长！
            case 's111': // 请求时间异常！
            case 's112': // 签名错误
            case 's113': // 商品未上架
            case 's117': // 不支持的号段!
            case 's118': // 请求的商品编码和请求的面额不一致！
                $status = self::FAIL;
                break;
            case 's104': // 流水号重复,请查询,通过查询接口查询!（预防重复充值）
            case 's115': // 数据异常,不能按照失败处理,需通过查询接口确认!
            case 's116': // 数据异常,不能按照失败处理,需通过查询接口确认!
            default: //  其它，或者网络异常		未确认（人工核实）或者通过查询接口确认
                $status = self::NEED_CONFIRM;
                break;
        }

        return compact('status', 'supplier_order_no', 'remark');
    }

    /**
     * 查询余额.
     *
     * 单位：分
     */
    public function queryAmount()
    {
        $params = [
            'agentcode' => $this->info['app_id'],
            'time' => date('YmdHis'),
        ];
        $params['sign'] = $this->getSign($params);
        $url = $this->info['url'] . '/api/md5/getbalance';
        $res = curlPost($url, http_build_query($params), $this->header);
        $res = json_decode($res, true);
        if (!isset($res['balance'])) {
            $this->error = $res['msg'] ?? '查询频繁';

            return false;
        }

        return yuan2fen($res['balance']);
    }

    /**
     * 订单查询.
     */
    public function query($orderId)
    {
        $params = [
            'agentcode' => $this->info['app_id'],
            'sellerid' => $orderId,
            'time' => date('YmdHis'),
        ];
        $params['sign'] = $this->getSign($params);
        $url = $this->info['url'] . '/api/md5/queryorder';
        $res = curlPost($url, http_build_query($params), $this->header);
        $res = json_decode($res, true);

        return $res;
    }

    /**
     * 生成签名.
     */
    public function getSign($params)
    {
        if (isset($params['sign'])) {
            unset($params['sign']);
        }

        $values = array_values($params);
        $values[] = $this->info['app_secret'];
        $sign = md5(implode('', $values));

        return $sign;
    }

    /**
     * 订单回调.
     */
    public function notify($params)
    {
        $insert = [
            'sub_order_id' => $params['sellerid'] ?? '',
            'params' => json_encode($params, JSON_UNESCAPED_UNICODE),
            'result' => 'ok',
        ];

        // $sign = $params['sign'] ?? '';
        // $checkSign = $this->getSign($params);
        // if ($sign !== $checkSign) {
        //     $insert['result'] = '验签失败';
        //     Db::name('mobile_notify')->insert($insert);

        //     return $insert['result'];
        // }

        $order = Db::name('mobile_order')
            ->where('sub_order_id', $params['sellerid'])
            ->where('mobile_supplier_id', $this->info['id'])
            ->find();
        if (empty($order)) {
            $insert['result'] = '订单不存在';
            Db::name('mobile_notify')->insert($insert);

            return 'fail';
        }

        if (in_array($order['supplier_status'], [3, 4, 99])) {
            $insert['result'] = '已经成功过';
            Db::name('mobile_notify')->insert($insert);

            return 'ok';
        }

        if ($order['supplier_status'] != 2) {
            $insert['result'] = '订单状态有误：' . $order['supplier_status'];
            Db::name('mobile_notify')->insert($insert);

            return 'fail';
        }

        // 供应商订单状态：1订单未创建 2订单已创建 3充值成功 4充值失败
        // 0表示充值中; 1表示已充值; 2表示充值失败;
        $supplierStatusMap = [
            2 => 3, // 1已充值 --> 3充值成功
            4 => 99, // 2充值失败 --> 充值失败，等待重试
            -11 => 99,
        ];
        $supplierStatus = $supplierStatusMap[$params['state']] ?? 2;
        if ($order['supplier_status'] == $supplierStatus) {
            Db::name('mobile_notify')->insert($insert);

            return 'ok';
        }
        $update = [
            // 'supplier_order_no' => '', // 没有返回
            'supplier_status' => $supplierStatus,
            'official_sn' => $params['voucher'] ?? '',  // 官方流水号
        ];
        if ($supplierStatus == 99) {
            // $update['refund_status'] = 2;   // 充值失败，退款
            $order['notify_url'] = '';  // 失败通知先不发
        }
        if (!empty($params['endtime'])) {
            $update['finish_time'] = strtotime($params['endtime']);
        }

        Db::name('mobile_notify')->insert($insert);

        Db::startTrans();
        try {
            // 如果是返佣模式，将订单结算方式改成待结算
            if ($supplierStatus == 3 && $order['settle_type'] == SETTLE_TYPE_PROFIT) {
                if ($order['profit'] == 0) {
                    $update['settle_status'] = 3;
                } elseif ($order['settle_status'] == 1) {
                    $update['settle_status'] = 2;
                }
            }

            Mobile::handleNotify($order, $update);

            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();

            $insert['result'] = '订单更新失败' . $order['id'] . '。' . $e->getMessage();
            Db::name('mobile_notify')->insert($insert);

            return 'fail';
        }

        return 'ok';
    }
}
